#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>

#define TASK_NUM 5

typedef void (*task_t)();

void DownLoad()
{
    printf("this is a download task is rnning!\n");
}
void PrintLog()
{
    printf("this is a write log task is rnning!\n");
}
void Show()
{
    printf("this is a show info task is rnning!\n");
}

void InitTasks(task_t tasks[], int num)
{
    int i = 0;
    for (; i < num; i++)
    {
        tasks[i] = NULL;
    }
}

int AddTask(task_t tasks[], task_t task)
{
    int i = 0;
    for (; i < TASK_NUM; i++)
    {
        if (tasks[i] == NULL)
        {
            tasks[i] = task;
            return 1;
        }
    }
    return -1;
}

void ExcuteTask(task_t tasks[], int num)
{
    for (int i = 0; i < num; i++)
    {
        if (tasks[i])
            tasks[i]();
    }
}

void Worker()
{
    int cnt = 5;
    while (cnt--)
    {
        printf("I am child process, pid: %d, ppid: %d, cnt: %d\n", getpid(), getppid(), cnt);
        sleep(2);
    }
}

int main()
{
    task_t tasks[TASK_NUM];
    InitTasks(tasks, TASK_NUM);
    AddTask(tasks, DownLoad);
    AddTask(tasks, PrintLog);
    AddTask(tasks, Show);

    pid_t id = fork();
    if (id == 0)
    {
        // child
        Worker();
        exit(0); // 退出码设置为10
    }
    else
    {
        while (1) // 非阻塞轮询
        {
            int status = 0; // 定义退出信息
            pid_t rid = waitpid(id, &status, WNOHANG);
            if (rid > 0) // 等待成功
            {
                printf("child quit success, pid: %d, exit sig: %d, exit code: %d\n", getpid(), status & 0x7F, (status >> 8) & 0xFF);
                break;
            }
            else if (rid == 0) // 等待成功，但并未退出
            {
                printf("------------------------\n");
                printf("child is alive, wait again, father do other thing....\n");
                // 可以设置一些任务...
                ExcuteTask(tasks, TASK_NUM);
                printf("------------------------\n");
            }
            else // 等待失败
            {
                printf("wait failed!\n");
                break;
            }
            sleep(1);
        }
    }
    return 0;
}
